package cn.xd.base.application.service.command.impl;

import cn.hutool.core.collection.CollUtil;
import cn.xd.base.application.service.command.AdminUserAppService;
import cn.xd.base.basic.type.AdminUserId;
import cn.xd.base.basic.type.AdminUserOrgRoleId;
import cn.xd.base.domain.bean.command.AddAdminUserCommand;
import cn.xd.base.domain.bean.command.UpdateAdminUserCommand;
import cn.xd.base.domain.bean.command.common.ChangeStatusCommand;
import cn.xd.base.domain.entity.AdminUser;
import cn.xd.base.domain.entity.AdminUserOrgRole;
import cn.xd.base.domain.repository.AdminUserRepository;
import cn.xd.base.persistence.dos.AdminOrgRoleDO;
import cn.xd.base.persistence.dos.AdminUserOrgRoleConverter;
import cn.xd.base.persistence.dos.AdminUserOrgRoleDO;
import cn.xd.base.persistence.mps.AdminOrgRoleMpService;
import cn.xd.base.persistence.mps.AdminUserOrgRoleMpService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class AdminUserAppServiceImpl implements AdminUserAppService {
    @Resource
    private AdminUserRepository adminUserRepository;
    @Resource
    private AdminOrgRoleMpService adminOrgRoleMpService;
    @Resource
    private AdminUserOrgRoleMpService adminUserOrgRoleMpService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addAdminUser(AddAdminUserCommand command, Long userId) {
        adminUserRepository.save(AdminUser.add(command, userId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAdminUser(UpdateAdminUserCommand command, List<Long> orgIds, Long userId) {
        AdminUser adminUser = adminUserRepository.find(AdminUserId.of(command.getId())).isEmptyThrow("当前用户不存在");
        List<AdminUserOrgRole> completeAdminUserOrgRole = getCompleteAdminUserOrgRole(command.getId(), orgIds);
        List<AdminUserOrgRole> adminUserOrgRoles = getAdminUserOrgRole(command.getId(), orgIds);
        adminUser.update(command, adminUserOrgRoles, completeAdminUserOrgRole, userId);
        adminUserRepository.save(adminUser);
    }

    /**
     * 补全 查询所有非当前机构的关系
     * 因为前端只能查询到当前机构及其下属机构
     *
     * @param userId
     * @param orgIds
     * @return
     */
    private List<AdminUserOrgRole> getCompleteAdminUserOrgRole(Long userId, List<Long> orgIds) {
        List<AdminOrgRoleDO> adminOrgRoleDOList = adminOrgRoleMpService.lambdaQuery().notIn(AdminOrgRoleDO::getOrgId, orgIds).list();
        return getAdminUserOrgRolesByOrgRoles(userId, adminOrgRoleDOList);
    }

    /**
     * 非补全（并排除超管）
     *
     * @param userId
     * @param orgIds
     * @return
     */
    private List<AdminUserOrgRole> getAdminUserOrgRole(Long userId, List<Long> orgIds) {
        List<AdminOrgRoleDO> adminOrgRoleDOList = adminOrgRoleMpService.lambdaQuery().in(AdminOrgRoleDO::getOrgId, orgIds).list();
        return getAdminUserOrgRolesByOrgRoles(userId, adminOrgRoleDOList);
    }

    private List<AdminUserOrgRole> getAdminUserOrgRolesByOrgRoles(Long userId, List<AdminOrgRoleDO> adminOrgRoleDOList) {
        List<AdminUserOrgRole> adminUserOrgRoles = new ArrayList<>();
        if (CollUtil.isNotEmpty(adminOrgRoleDOList)) {
            List<Long> adminOrgRoleIds = adminOrgRoleDOList.stream().map(AdminOrgRoleDO::getId).toList();
            if (CollUtil.isNotEmpty(adminOrgRoleIds)) {
                List<AdminUserOrgRoleDO> adminUserOrgRoleDOList = adminUserOrgRoleMpService.lambdaQuery().eq(AdminUserOrgRoleDO::getUserId, userId)
                        .in(AdminUserOrgRoleDO::getOrgRoleId, adminOrgRoleIds).list();
                adminUserOrgRoles = AdminUserOrgRoleConverter.INSTANCE.fromData(adminUserOrgRoleDOList);
            }
        }
        return adminUserOrgRoles;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeAdminUserStatus(ChangeStatusCommand command, Long userId) {
        AdminUser adminUser = adminUserRepository.find(AdminUserId.of(command.getId())).isEmptyThrow("当前角色不存在");
        adminUser.changeStatus(command, userId);
        adminUserRepository.save(adminUser);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id, List<Long> orgIds) {
        AdminUser adminUser = adminUserRepository.find(AdminUserId.of(id)).isEmptyThrow("当前角色不存在");
        List<Long> userOrgRoleId = getCompleteAdminUserOrgRole(id, orgIds).stream().map(AdminUserOrgRole::getId).map(AdminUserOrgRoleId::getValue).toList();

        if (CollUtil.isEmpty(userOrgRoleId)) {
            adminUserOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminUserOrgRoleDO.class).eq(AdminUserOrgRoleDO::getUserId, id));
            adminUserRepository.remove(adminUser);
        } else {
            adminUserOrgRoleMpService.remove(Wrappers.lambdaQuery(AdminUserOrgRoleDO.class).eq(AdminUserOrgRoleDO::getUserId, id)
                    .notIn(AdminUserOrgRoleDO::getId, userOrgRoleId)
            );
        }

    }
}
